﻿using LPLS.Commons.Enums;
using LPLS.DBEntities.OEEModule.OEEModels.DataStatisticModels;
using LPLS.DBInterface.OEEModule.OEEModels.DataStaticsticModels;
using LPLS.DBInterface.OEEModule.OEEModels.TimeUtilizationModels;
using OxyPlot;
using OxyPlot.Annotations;
using OxyPlot.Axes;
using OxyPlot.Legends;
using OxyPlot.Series;
using Prism.Mvvm;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DataStatisticsChartModule.ViewModels
{
    public class TimeUtilizationViewModel : BindableBase
    {
        /// <summary>
        /// 组件统计接口
        /// </summary>
        private readonly ICompentDataStatisticsService _compentDataStatisticsService;
        /// <summary>
        /// 时间稼动率计算规则配置接口
        /// </summary>
        private readonly ITimeUtilizationRateConfigService _timeUtilizationRateConfigService;

        public TimeUtilizationViewModel(ICompentDataStatisticsService compentDataStatisticsService
            , ITimeUtilizationRateConfigService timeUtilizationRateConfigService


            )
        {
            _compentDataStatisticsService = compentDataStatisticsService;
            _timeUtilizationRateConfigService = timeUtilizationRateConfigService;
            DataStatisticsEvent.OnDataStatisticsEvent += DataStatisticsEvent_OnDataStatisticsEvent;
        }

        private DataStatisticsEventModel eventModel;

        private void DataStatisticsEvent_OnDataStatisticsEvent(DataStatisticsEventModel model)
        {
            eventModel = model;
            LoadData();
        }



        private List<CompentDataStatistics> DbData = new List<CompentDataStatistics>();

        private void LoadData()
        {


            var data = _compentDataStatisticsService.GetData(eventModel.StartTime, eventModel.EndTime, eventModel.DeviceModel.ID);
            DbData = data;
            ///炉管稼动率
            TubeTimeUtilizationRateByTimeModel= QueryCompentTimeUtilizationRateByTimeToLineBar(DbData, DeviceComponentTypeEnum.Tube,"炉管稼动率" );
            ManipulatorTimeUtilizationRateByTimeModel= QueryCompentTimeUtilizationRateByTimeToLineBar(DbData, DeviceComponentTypeEnum.J, "机械手稼动率");




        }


        /// <summary>
        /// 时间稼动率  炉管的 全部使用这个
        /// </summary>
        /// <param name="data"></param>
        private PlotModel QueryCompentTimeUtilizationRateByTimeToLineBar(List<CompentDataStatistics> data, DeviceComponentTypeEnum compent,string title)
        {
            var timeinterval = SelectDateStringByDate(eventModel);
            var model = new PlotModel();
            model.Title = title;
            /*
             1.首先需要筛选出 炉管数据  
             2.每一个炉管一个Serial 所以根据 部件的ID 进行分组 
             */
            //1.获取炉管数据
            var tubedata = data.Where(e => e.CompentTypeEnum == compent).ToList();
            //2.每一个炉管一个Serial 所以根据 部件的ID 进行分组 
            var tubeserialdata = tubedata.GroupBy(e => e.ComponentName).ToList();
            //3. 每一组数据代表一个 Serial  
            var series = new List<LineSeries>();
            //4.加载计算规则
            var timeUtilizationRateConfigData = _timeUtilizationRateConfigService.GetData(eventModel.DeviceModel.ID, compent);
            ///4.1  负荷时间 所配置的状态
            var loadtimedata = timeUtilizationRateConfigData.Where(e => e.Type == 1).Select(d => d.Status).ToList();
            //4.2   停机时间 所配置的状态
            var stoptimedata = timeUtilizationRateConfigData.Where(e => e.Type == 2).Select(d => d.Status).ToList();
            // 5.接下来 需要从2 中的分组数据 进行数据整合
            foreach (var item in tubeserialdata)//所有 管数据
            {
                var li = new List<Pn>();
                IEnumerable<GroupResult<int, CompentDataStatistics>> groupdatata = null;
                switch (timeinterval)
                {

                    //按照年分
                    case 0:

                        groupdatata = item.GroupBy(obj=>obj.StartTime.Year).Select(group =>  new GroupResult<int, CompentDataStatistics>
                        {
                            Key = group.Key,
                            Items = group.ToList()
                        }
                        );
                     
                        break;

                    //按照小时分
                    case 24:

                        groupdatata = item.GroupBy(obj => obj.StartTime.Hour).Select(group => new GroupResult<int, CompentDataStatistics>
                        {
                            Key = group.Key,
                            Items = group.ToList()
                        }
                      );
                        break;
                    //按照天 分
                    case 30:
                        groupdatata = item.GroupBy(obj => obj.StartTime.Day).Select(group => new GroupResult<int, CompentDataStatistics>
                        {
                            Key = group.Key,
                            Items = group.ToList()
                        }
                      );
                        break;
                    //按照月分
                    case 12:

                        groupdatata = item.GroupBy(obj => obj.StartTime.Month).Select(group => new GroupResult<int, CompentDataStatistics>
                        {
                            Key = group.Key,
                            Items = group.ToList()
                        }
                      );
                        break;
                    default:
                        break;
                }
                foreach (var item3 in groupdatata)
                {
                    double loadtime = 0;
                    double stoptime = 0;

                    foreach (var item2 in item3.Items)
                    {
                        var loadflag = loadtimedata.Where(e => e == item2.Status).ToList();
                        ///负荷时间有该数据
                        if (loadflag.Count>0)
                        {
                            loadtime += item2.TotalSecondTime;
                        }
                        var stopflag = stoptimedata.Where(e => e == item2.Status).ToList();
                        if (stopflag.Count>0)
                        {
                            stoptime += item2.TotalSecondTime;
                        }
                    }
                    var result = (loadtime - stoptime) / loadtime * 100;
                    var time = item3.Items.LastOrDefault().StartTime;
                    Pn m = new Pn();
                    m.Time = time; ;
                    m.Value = result;
                    li.Add(m);
                }
                var myseries = new LineSeries
                {
                    Title = item.Key,
                    ItemsSource = li,
                    DataFieldX = "Time",
                    DataFieldY = "Value",
                    MarkerType = MarkerType.Circle,

                };
                series.Add(myseries);
            }
            foreach (var item in series)
            {
                model.Series.Add(item);
            }
            var annotation = new LineAnnotation
            {
                Type = LineAnnotationType.Horizontal,
                Y = 0
            };
            model.Annotations.Add(annotation);
            var dateTimeAxis = new DateTimeAxis
            {
                Position = AxisPosition.Bottom,
                IntervalType = DateTimeIntervalType.Auto,
            };
            model.Axes.Add(dateTimeAxis);
            var valueAxis = new LinearAxis
            {
                Position = AxisPosition.Left,
                Minimum =-10,
                Maximum = 120,
                Title="稼动率 （%）"              
            };
            model.Axes.Add(valueAxis);
            Legend l = new Legend();
            l = GetLegend();
            model.Legends.Add(l);
             return  model;

        }









        public class GroupResult<TKey, TElement>
        {
            public TKey Key { get; set; }
            public List<TElement> Items { get; set; }
        }
        private PlotModel _TubeTimeUtilizationRateByTimeModel;
        /// <summary>
        /// 炉管的时间稼动率再某一个时间段内
        /// </summary>
        public PlotModel TubeTimeUtilizationRateByTimeModel
        {
            get { return _TubeTimeUtilizationRateByTimeModel; }
            set
            {
                SetProperty(ref _TubeTimeUtilizationRateByTimeModel, value);
            }
        }
        private PlotModel _ManipulatorTimeUtilizationRateByTimeModel;
        public PlotModel ManipulatorTimeUtilizationRateByTimeModel
        {
            get { return _ManipulatorTimeUtilizationRateByTimeModel; }
            set { SetProperty(ref _ManipulatorTimeUtilizationRateByTimeModel, value); }
        }
        private double SelectDateStringByDate(DataStatisticsEventModel model)
        {

            var mindate = model.StartTime;

            var maxdate = model.EndTime;

            TimeSpan timeDifference = maxdate - mindate;

            if (timeDifference.TotalDays <= 2)
            {
                return 24;

            }
            if (timeDifference.TotalDays > 2 && timeDifference.TotalDays < 30)
            {
                return 30;
            }
            if (timeDifference.TotalDays > 30 && timeDifference.TotalDays < 365)
            {
                return 12;
            }
            else
            {

                return 24;

            }
        }
        private Legend GetLegend()
        {
            Legend legend = new Legend()
            {

                LegendBorder = OxyColors.Black,
                LegendBackground = OxyColor.FromAColor(200, OxyColors.White),
                LegendPosition = LegendPosition.LeftTop,
                LegendPlacement = LegendPlacement.Outside,
                LegendOrientation = LegendOrientation.Horizontal,
                LegendItemOrder = LegendItemOrder.Normal,
                LegendItemAlignment = HorizontalAlignment.Left,
                LegendSymbolPlacement = LegendSymbolPlacement.Right,

            };

            return legend;

        }
    }


    public class Pn

    {

        public double FinalX { get; set; }
        public double FinalY { get; set; }
        public double X { get; set; }
        public double Y { get; set; }

        public DateTime Time
        {
            get { return DateTimeAxis.ToDateTime(this.X, DateTimeAxis.DefaultPrecision); }
            set
            {
                var finalX = DateTimeAxis.ToDouble(value);

                this.FinalX = finalX;
                this.X = finalX;
            }
        }

        public double Value
        {
            get { return this.Y; }
            set
            {
                this.FinalY = value;
                this.Y = value;
            }
        }

        public override string ToString()
        {
            return String.Format("{0:HH:mm} {1:0.0}", this.Time, this.Value);
        }


    }
}
